﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.UI;


namespace MDXTest
{
    public partial class Form1 : Form
    {
        MicCapture capture;
        Thread captureThread;
        Image<Gray, byte> fourierHistgram;
        int currentIndex;

        const int ImageWidth = 500;
        const int ImageHeight = 500;

        public Form1()
        {
            InitializeComponent();
            capture = new MicCapture(1, 44100, 1, 16);

            fourierHistgram = new Image<Gray, byte>(ImageWidth, ImageHeight);
            imageBox1.Image = fourierHistgram;
        }

        private void button_Record_Click(object sender, EventArgs e)
        {
            capture.StartCapture(100);

            Thread captureThread = new Thread(new ThreadStart(CaptureThreadProc));
            captureThread.Start();
            currentIndex = 0;
        }

        private void button_Stop_Click(object sender, EventArgs e)
        {
            capture.StopCapture();
            captureThread.Abort();
        }

        private void updateImage(Matrix<byte> f_line)
        {
            if (currentIndex >= ImageWidth - 1) {
                currentIndex--;
            }
            if (currentIndex > 0)
            {
                fourierHistgram.GetSubRect(new Rectangle(ImageWidth - currentIndex - 1, 0, currentIndex, ImageHeight))
                    .CopyTo(fourierHistgram.GetSubRect(new Rectangle(ImageWidth - currentIndex - 2, 0, currentIndex, ImageHeight)));
            }
            f_line.CopyTo(fourierHistgram.GetSubRect(new Rectangle(ImageWidth - 2, 0, 1, ImageHeight)));
            currentIndex++;
        }

        private void RefreshImage()
        {
            imageBox1.Refresh();
        }

        private void CaptureThreadProc()
        {
            do
            {
                SoundData data = capture.QueryFrame();
                if (data == null)
                {
                    continue;
                }
                SoundData fourier = data.Fourier();

                double min, max;
                Point min_loc, max_loc;
                fourier.Data.MinMax(out min, out max, out min_loc, out max_loc);
                fourier.Data /= 3000000;
                fourier.Data *= 255;

                Matrix<byte> f_line = new Matrix<byte>(ImageHeight, 1);
                CvInvoke.cvResize(fourier.Data.Convert<byte>().Ptr, f_line.Ptr, INTER.CV_INTER_CUBIC);

                updateImage(f_line);

                Invoke(new MethodInvoker(RefreshImage));
            }
            while (capture.CaptureBuffer.Capturing);
        }

        
    }
}
